
#ifndef _BSP_UART_C
#define _BSP_UART_C

/********************************************************************************************
*file description:
*
*
*
*Created by Evan @2025/02/18
*Copyright (c) 2025,  Inc.
********************************************************************************************/
/********************************************************************************************
* include:
********************************************************************************************/
#include "BSP_Config.h"
#include "sys_config.h"
#include "bsp_uart.h"

/********************************************************************************************
* Define:
********************************************************************************************/


/********************************************************************************************
* Datas:
********************************************************************************************/
#if UART0_RX_SIZE > 0
static uint8_t uart0_rxBuf[UART0_RX_SIZE];
static uint16_t uart0_rxBufHead = 0;
static uint16_t uart0_rxBufTail = 0;
#else
#define uart0_rxBuf 0
#define uart0_rxBufTail RAM16(0)
#endif
#if UART1_RX_SIZE > 0
static uint8_t uart1_rxBuf[UART1_RX_SIZE];
static uint16_t uart1_rxBufHead = 0;
static uint16_t uart1_rxBufTail = 0;
#else
#define uart1_rxBuf 0
#define uart1_rxBufTail RAM16(0)
#endif

// DMA串口数组定义
const struct uartDmaDevType uartDmaDevTab[UART_DMA_DEV_NUM] = {
    {USART0, DMA, uart0_rxBuf, &uart0_rxBufHead, &uart0_rxBufTail, UART0_RX_SIZE, DMA_CH2, DMA_CH1, DMA_Channel1_2_IRQn, DMA_Channel1_2_IRQn, USART0_IRQn},
    {USART1, DMA, uart1_rxBuf, &uart1_rxBufHead, &uart1_rxBufTail, UART1_RX_SIZE, DMA_CH4, DMA_CH3, DMA_Channel3_4_IRQn, DMA_Channel3_4_IRQn, USART1_IRQn},
};

/********************************************************************************************
* Function:
********************************************************************************************/
/********************************************************************************************
* Function Name  : bsp_uart_init
* Description    : 串口初始化
* Input          : 
                   uint8_t  uart_id 串口ID
                   uint32_t baud    通信波特率
* Output         : void
* Return         : none
********************************************************************************************/
void bsp_uart_init(uint8_t uart_id, uint32_t baud)
{
    uint8_t rxDmaEn = 0, txDmaEn = 0;
    uint32_t uclk = 0U, intdiv = 0U, fradiv = 0U, udiv = 0U;

    /* enable clock */
	rcu_periph_clock_enable(RCU_DMA);

    switch (uart_id)
    {
#if IS_USE_UART(0)
    case 0:
        rcu_periph_clock_enable(RCU_USART0);
		rcu_periph_clock_enable(RCU_GPIOA);

		/* connect port to USARTx_Tx */
		gpio_out_config(GPIOA,9);
		/* connect port to USARTx_Rx */
		gpio_out_config(GPIOA,10);

		/* reset USART0 */
		rcu_periph_reset_enable(RCU_USART0RST);
		rcu_periph_reset_disable(RCU_USART0RST);
	
		rxDmaEn = 1;
		txDmaEn = 1;
        break;
#endif

#if IS_USE_UART(1)
    case 1:
        rcu_periph_clock_enable(RCU_USART1);
		rcu_periph_clock_enable(RCU_GPIOA);

		/* connect port to USARTx_Tx */
        gpio_out_config(GPIOA,2);
		/* connect port to USARTx_Rx */
        gpio_in_config(GPIOA,3);
	
		rcu_periph_reset_enable(RCU_USART1RST);
		rcu_periph_reset_disable(RCU_USART1RST);
	
		rxDmaEn = 1;
		txDmaEn = 1;
        break;
#endif
    default:
        break;
    }

    /* USART configure */
    udiv = (uclk + baud / 2U) / baud;
    intdiv = udiv & 0xfff0U;
    fradiv = udiv & 0x000fU;
    USART_BAUD(uartDmaDevTab[uart_id].uartAdd) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv));
    USART_CTL0(uartDmaDevTab[uart_id].uartAdd) |= USART_RECEIVE_ENABLE | USART_TRANSMIT_ENABLE;

    if (rxDmaEn)
    {
        DMA_CHCTL(uartDmaDevTab[uart_id].rxDmaCh) = 0;
        DMA_CHPADDR(uartDmaDevTab[uart_id].rxDmaCh) = (uint32_t)(&USART_RDATA(uartDmaDevTab[uart_id].uartAdd));

        DMA_CHCNT(uartDmaDevTab[uart_id].rxDmaCh) = uartDmaDevTab[uart_id].rxDmaBufSize;
        DMA_CHMADDR(uartDmaDevTab[uart_id].rxDmaCh) = (uint32_t)(uartDmaDevTab[uart_id].rxDmaBuf);
        DMA_CHCTL(uartDmaDevTab[uart_id].rxDmaCh) = BIT(5) | BIT(7) | BIT(12) | BIT(13);
        // DMA_INTC |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, uartDmaDevTab[uart_id].rxDmaCh);
        DMA_CHCTL(uartDmaDevTab[uart_id].rxDmaCh) |= DMA_CHXCTL_CHEN;

        USART_CTL2(uartDmaDevTab[uart_id].uartAdd) |= USART_DENR_ENABLE;
    }

    if (txDmaEn)
    {
        DMA_CHCTL(uartDmaDevTab[uart_id].txDmaCh) = 0;
        DMA_CHPADDR(uartDmaDevTab[uart_id].txDmaCh) = (uint32_t)(&USART_TDATA(uartDmaDevTab[uart_id].uartAdd));

        DMA_CHCNT(uartDmaDevTab[uart_id].txDmaCh) = 0;
        DMA_CHMADDR(uartDmaDevTab[uart_id].txDmaCh) = 0;
        DMA_CHCTL(uartDmaDevTab[uart_id].txDmaCh) = BIT(4) | BIT(7) | BIT(12) | BIT(13);
        // DMA_INTC |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, uartDmaDevTab[uart_id].txDmaCh);

        USART_CTL2(uartDmaDevTab[uart_id].uartAdd) |= USART_DENT_ENABLE;
    }

    USART_CTL0(uartDmaDevTab[uart_id].uartAdd) |= USART_CTL0_UEN;
}

#endif
